﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ApplLogic.ApplClasses;
using TCPClient.UI.LogicForUserControls;
using EventHandler = TCPClient.UI.UserControls.EventHandler;

namespace TCPClient.UI
{
    public partial class AlgoExecuterForm : Form
    {
        public event EventHandler AlgoFinished = null;
        private List<ApplWorker> m_WorkersThatSentRequests = new List<ApplWorker>();
        private List<ApplWorker> m_WorkersThatNotSentRequests = new List<ApplWorker>();

        public AlgoExecuterForm()
        {
            InitializeComponent();
            setAllFromServer();
        }

        private ApplWorker getWorkerByName(string name)
        {
            return m_WorkersThatNotSentRequests.FirstOrDefault(worker => worker.PersonalDetails.FullName == name);
        }

        private void setAllFromServer()
        {
            setNumericValuesFromServer();
            setDateLabel();
            setWorkersThatSentRequests();
            setWorkersThatNotSentRequests();
            setSomeShit();
        }

        private void setSomeShit()
        {
            Size = m_WorkersThatNotSentRequests.Count > 0 ? new Size(998, 456) : new Size(824, 456);
            progressBarAlgo.Size = m_WorkersThatNotSentRequests.Count > 0 ? new Size(972, 35) : new Size(820, 35);
            WorkerNames names = new WorkerNames();
            names.Names = new List<string>();
            names.Names.Add("Choose Worker");
            foreach (ApplWorker worker in m_WorkersThatNotSentRequests)
            {
                names.Names.Add(worker.PersonalDetails.FullName);
            }
            comboBoxNotSent.DataSource = names.Names;
        }

        private void setNumericValuesFromServer()
        {
            numericUpDownPeriodBetweenShifts.Value =
                int.Parse(ScMainUserControlLogicManager.Instance.GetDefaultPeriodBetweenShiftsForRunningAlgo());

            numericUpDownMinshiftNumForWorker.Value =
                int.Parse(ScMainUserControlLogicManager.Instance.GetMinNumberOfShiftsPerDay());
        }

        private void setDateLabel()
        {
            labelDate.Text = string.Format("{0} - {1}",
                                                ScMainUserControlLogicManager.Instance.StartTimeOfCurrentWeek.AddDays(7).
                                                    ToShortDateString(),
                                                ScMainUserControlLogicManager.Instance.EndTimeOfCurrentWeek.AddDays(7).
                                                    ToShortDateString());
        }

        private void setWorkersThatSentRequests()
        {
            textBoxSentRequests.Text = "";
            this.labelSumSent.Text = @"Total:";
            m_WorkersThatSentRequests = ScMainUserControlLogicManager.Instance.GetAllWorkersThatAskedForShiftsInRange();
            foreach (var worker in m_WorkersThatSentRequests)
            {
                textBoxSentRequests.AppendText(string.Format("{0}\n", worker.PersonalDetails.FullName));
            }
            this.labelSumSent.Text += (@" " + m_WorkersThatSentRequests.Count);
        }

        private void setWorkersThatNotSentRequests()
        {
            textBoxNotSentRequests.Text = "";
            this.labelSumNotSent.Text = @"Total:";
            m_WorkersThatNotSentRequests = ScMainUserControlLogicManager.Instance.GetAllWorkersThatNotAskedForanyShiftInRange();
            buttonNotifyNotSent.Visible = m_WorkersThatNotSentRequests.Count > 0;
            foreach (var worker in m_WorkersThatNotSentRequests)
            {
                textBoxNotSentRequests.AppendText(string.Format("{0}\n", worker.PersonalDetails.FullName));
            }
            this.labelSumNotSent.Text += (@" " + m_WorkersThatNotSentRequests.Count);
        }

        private void buttonExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void buttonRunAlgo_Click(object sender, EventArgs e)
        {
            updateServerWithConstraints();
            progressBarAlgo.Visible = true;
            progressBarAlgo.Maximum = 300;
            disableAll();
            this.timer1.Start();
            Thread thread = new Thread(runAlgo);
            thread.Start();
        }

        private void runAlgo()
        {
            ScMainUserControlLogicManager.Instance.RunAlgo();
            if(checkBoxNotify.Checked)
            {
                ScMainUserControlLogicManager.Instance.NotifyAllWorkersForNewShiftCreation("");
            }
        }

        private void disableAll()
        {
            numericUpDownMinshiftNumForWorker.Enabled = false;
            numericUpDownPeriodBetweenShifts.Enabled = false;
            checkBoxForbiddenShift.Enabled = false;
            checkBoxShiftLinitations.Enabled = false;
            buttonExit.Enabled = false;
            buttonRunAlgo.Enabled = false;
            checkBoxNotify.Enabled = false;
        }

        private void updateServerWithConstraints()
        {
            ScMainUserControlLogicManager.Instance.ChangeDefaultPeriodBetweenShiftsForRunningAlgo(
                this.numericUpDownPeriodBetweenShifts.Value.ToString());
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            progressBarAlgo.Increment(1);
            if (progressBarAlgo.Value == 300)
            {
                algoFinished();
            }
        }

        private void algoFinished()
        {
            timer1.Stop();
            progressBarAlgo.Value = 0;
            string title = checkBoxNotify.Checked
                               ? "Registraition Finished And Workers were notifiied"
                               : "Registraition Finished";
            string body = checkBoxNotify.Checked
                              ? "Automatic Shift Organizor finished registrations And Workers were notifiied with new work order"
                              : "Automatic Shift Organizor finished registrations";
            MessageBox.Show(body, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
            // nootify observers that algo finished running
            if(AlgoFinished != null)
            {
                AlgoFinished.Invoke(this, null);
            }
            Close();
        }

        private void buttonNotifyNotSent_Click(object sender, EventArgs e)
        {
            PublishWorkOrderForm pfm = new PublishWorkOrderForm(eNotificationType.NotifyForMissingRequests);
            pfm.ShowDialog();
        }

        private void comboBoxNotSent_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            if ((comboBox.SelectedValue as string) != "Choose Worker")
            {
                SendWorkerRequestFroManagerForm srf =
                    new SendWorkerRequestFroManagerForm(getWorkerByName(comboBox.SelectedValue as string));
                srf.FormClosed += doWhenSrfFromClosed;
                srf.ShowDialog();
            }
        }

        private void doWhenSrfFromClosed(object sender, EventArgs e)
        {
            this.setAllFromServer();
            comboBoxNotSent.SelectedIndex = 0;
        }

        private class WorkerNames
        {
            public List<string> Names { get; set; }
        }
    }
}
